//
//  TwitterMediaShareCommunity.m
//  MediaShareBB
//
//  Created by Artak Gevorgyan on 7/4/13.
//  Copyright (c) 2013 InnoriseEntertainment. All rights reserved.
//

#import "AppDelegate.h"
#import "TwitterMediaShareCommunity.h"
#import "MediaShareData.h"
#import "MediaShareBBUtilityMethods.h"
#import "SimpleQueue.h"
#import "SimpleOperation.h"
#import "SimpleTwitterRequest.h"
#import "OAuth.h"
#import "SimpleTwitterLoginViewController.h"

#import <Twitter/Twitter.h>
#import <Social/Social.h>
#import <Accounts/Accounts.h>

@interface TwitterMediaShareCommunity()<OAuthTwitterCallbacks,
										SimpleTwitterLoginViewControllerDelegate>
{
	MediaShareData* _sharedMediaData;
	NSString* _consumerKey;
	NSString* _consumerSecret;
	NSString* _callbackUrl;

	SimpleQueue* _queue;
	OAuth* _oAuth;
	BOOL _cacheToken;
	BOOL _optimize;
	SimpleTwitterLoginViewController* _login;
}

@end

@implementation TwitterMediaShareCommunity

-(id) init {
	self = [super init];
	if (self) {
		super.name = @"Twitter";
		super.communityType = MEDIA_SHARE_COMMUNITY_TWITTER;
		super.supportedMediaTypes = [[NSArray alloc] initWithObjects:
									 [NSNumber numberWithInt:IMAGE_MEDIA_TYPE], nil];
	}
	return self;
}

#pragma mark - Superclass methods

// Superclass method
-(NSString*) description {
	NSString* d = @"Twitter description";
	return d;
}

// Superclass method
-(void) configureWithCredentials:(NSDictionary*) credentials {
	_consumerKey = [credentials valueForKey:@"consumerKey"];
	_consumerSecret = [credentials valueForKey:@"consumerSecret"];
	_callbackUrl = [credentials valueForKey:@"callbackUrl"];

	_queue = [[SimpleQueue alloc] init];
	_oAuth = [[OAuth alloc] initWithConsumerKey:MEDIA_SHARE_BB_TWITTER_CONSUMER_KEY
							  andConsumerSecret:MEDIA_SHARE_BB_TWITTER_CONSUMER_SECRET];
	_callbackUrl = MEDIA_SHARE_BB_TWITTER_CALLBACK_URL;
	_oAuth.delegate = self;
	_cacheToken = YES;
	_optimize = TRUE;
}

// Superclass method
-(void) login {
    if ([self canProceedRequestToShareWithNativeDialog]) {
        self.isNativeMode = YES;
        if ([MediaShareBBUtilityMethods isObject:super.delegate
                              respondsToSelector:@selector(loginSuccess)]) {
            [super.delegate loginSuccess];
        }
    } else {
        self.isNativeMode = NO;
        if (![self isAuthenticated]) {            
			[self prepareLoginViewController];
        } else {
            [super.delegate loginSuccess];
        }
    }
}

//Superclass method
-(void) loginWithAnotherUser {
    [_oAuth forget];
    [self prepareLoginViewController];
}

//Superclass method
-(NSString*) getUserName {
    return [_oAuth screen_name];
}

//Superclass method
-(NSString*) sharedMediaLink {
    return @"";
}

// Superclass method
-(void) shareMedia:(MediaShareData*) data {
	if ([super isValidMediaType:data.mediaType]) {
		_sharedMediaData = data;
		[self performPost];
	} else {
		NSLog(@"%s: Unsupported media type:%d", __PRETTY_FUNCTION__, data.mediaType);
	}
}

#pragma mark - OAuthTwitterCallbacks methods

-(void) requestTwitterTokenDidSucceed:(OAuth*) oAuth {
    NSLog(@"%s: Twitter Request Token did succeed", __PRETTY_FUNCTION__);
}

-(void) requestTwitterTokenDidFail:(OAuth*) oAuth {
    NSLog(@"%s: Twitter Request Token did fail", __PRETTY_FUNCTION__);
}

-(void) authorizeTwitterTokenDidSucceed:(OAuth*) oAuth {
    NSLog(@"%s: Twitter Authorize Token did succeed", __PRETTY_FUNCTION__);
}

-(void) authorizeTwitterTokenDidFail:(OAuth*) oAuth {
    NSLog(@"%s: ++ Twitter Authorize Token did fail", __PRETTY_FUNCTION__);
}

#pragma mark - SimpleTwitterLoginViewControllerDelegate methods

-(void) loginViewControllerDidSucceed:(id) sender {
    if ([MediaShareBBUtilityMethods isObject:super.delegate
						  respondsToSelector:@selector(loginSuccess)])  {
        [super.delegate loginSuccess];
    }

    // ** Dismiss the Controller **
    // Some may prefer to dismiss the modal view controller in the delegate,
    // but this software is designed to be "simple", so that clients can implement
    // the social services with the minimal amount of hassle, and that includes
    // handling view controllers, ui components, etc. If you desire to handle the
    // dismissal in the delegate, simply comment out this portion, and/or deactivate
    // the "optimization" flag, and then implement the dismissal in the callback which
    // is invoked above.
    if (_optimize ) {
        [self dismissViewController];
    }

    // Process the queue
    [self processQueue];
}

-(void) loginViewControllerDidLoad:(id) sender {
//    // Remove the HUDs
//    [MBProgressHUD hideAllHUDsForView:[self.delegate targetViewController].view animated:YES];
//
    if (_login.usePreloading ) {
		_login.preloading = NO;
        [self presentViewController:_login];
    }
}

-(void) loginViewControllerDidFail:(id) sender {
//    // Remove the HUDs
//    [MBProgressHUD hideAllHUDsForView:[self.delegate targetViewController].view animated:YES];
//
//    // Clear out queue and signal delegate
//    if ( self.login.preloading ) {
//        self.login.preloading = NO;
//        [self.queue clear];
//
//        // Signal to delegate
//        if ( self.delegate != nil && [self.delegate respondsToSelector:@selector(simpleTwitterDidFail:withHeaders:)] ) {
//            NSDictionary *params = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObject:@"Preloading failed"] forKeys:[NSArray arrayWithObject:@"error"]];
//            [self.delegate simpleTwitterDidFail:self withHeaders:params];
//        }
//    }
}

-(void) loginViewControllerDidCancel:(id) sender {
    // Clear out the queue
    [_queue clear];

    // Signal to delegate
    if ([MediaShareBBUtilityMethods isObject:super.delegate
						  respondsToSelector:@selector(loginCanceled)]) {
        [super.delegate loginCanceled];
    }

    // ** Dismiss the Controller **
    // Again, as above, some users may prefer to let the delegate perform this dismissal.
    if (_optimize ) {
        [self dismissViewController];
    }
}

#pragma mark - NSURLConnectionDelegate methods

-(void) connection:(NSURLConnection*) connection
		didReceiveResponse:(NSHTTPURLResponse*) response {
    if (!_cacheToken ) {
		_oAuth.oauth_token_authorized = NO;
	}
    switch ( response.statusCode ) {
        case 200:
			if ([MediaShareBBUtilityMethods isObject:super.delegate
								  respondsToSelector:@selector(didFinishSharingMedia:through:)]) {
				[super.delegate didFinishSharingMedia:_sharedMediaData
											  through:self];
			}
            break;
        default: {
			NSDictionary* params = [NSDictionary dictionaryWithObjects:
									[NSArray arrayWithObject:[NSHTTPURLResponse localizedStringForStatusCode:response.statusCode]]
															   forKeys:[NSArray arrayWithObject:@"error"]];
			NSLog(@"%s: response.status code = %d, params = %@", __PRETTY_FUNCTION__,
													response.statusCode, params);
			if ([MediaShareBBUtilityMethods isObject:super.delegate
								  respondsToSelector:@selector(didFailedSharingMedia:through:withError:)]) {
				NSError* error = [[NSError alloc] init];
				error = [NSString stringWithFormat:@"Twitter post failed with status code %d", response.statusCode];
				if ([MediaShareBBUtilityMethods isObject:super.delegate
									  respondsToSelector:@selector(didFailedSharingMedia:through:withError:)]) {
					[super.delegate didFailedSharingMedia:_sharedMediaData
												  through:self
												withError:error];
				}
			}
            break;
		}
    }
}

-(void) connection:(NSURLConnection*) connection didFailWithError:(NSError*) error {
	NSDictionary* params = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObject:error.localizedDescription]
													   forKeys:[NSArray arrayWithObject:@"error"]];
	NSLog(@"%s: params = %@", __PRETTY_FUNCTION__, params);
	if ([MediaShareBBUtilityMethods isObject:super.delegate
						  respondsToSelector:@selector(didFailedSharingMedia:through:withError:)]) {
		[super.delegate didFailedSharingMedia:_sharedMediaData
									  through:self
									withError:nil];
	}
}

#pragma mark - Private methods

-(void) prepareLoginViewController {
	if (_login != nil ) {
		_login = nil;
	}
	_login = [[SimpleTwitterLoginViewController alloc] init];
	_login.delegate = self;
	_login.oAuth = _oAuth;
	_login.callbackURL = _callbackUrl;
	double delayInSeconds =  0.1f;
	dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW,
											(int64_t)(delayInSeconds * NSEC_PER_SEC));
	dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
		_login.usePreloading = YES;
		[_login prepareRequest];
	});
}

-(void) presentViewController:(UIViewController*) vc {
    if ([MediaShareBBUtilityMethods isObject:super.delegate
						  respondsToSelector:@selector(targetViewController)] ) {
//        UIViewController* controller = [super.delegate targetViewController];
		AppDelegate* app = [UIApplication sharedApplication].delegate;
        UIViewController* controller = app.window.rootViewController;
        if (IPAD) {
			_login.modalPresentationStyle = UIModalPresentationFormSheet;
        }
		if ( [controller respondsToSelector:
			  @selector(presentViewController:animated:completion:)] ) {
			[controller presentViewController:vc animated:YES completion:nil];
		} else if ( [controller respondsToSelector:
					 @selector(presentModalViewController:animated:)] ) {
			[controller presentViewController:vc animated:YES completion:nil];
		}
    }
}

-(void) dismissViewController {
	AppDelegate* app = [UIApplication sharedApplication].delegate;
	UIViewController* controller = app.window.rootViewController;
//	UIViewController* controller = [super.delegate targetViewController];
    if ( [controller respondsToSelector:@selector(dismissViewControllerAnimated:completion:)] ) {
        [controller dismissViewControllerAnimated:YES completion:nil];
    } else if ( [controller respondsToSelector:@selector(dismissModalViewControllerAnimated:)] ) {
        [controller dismissViewControllerAnimated:YES completion:nil];
    }
}

-(void) processQueue {
    if ([_queue size] > 0 ) {
        while ( [_queue size] > 0 ) {
            SimpleOperation *op = (SimpleOperation*)[_queue dequeueObj];
            [self process:op];
        }
    }
}

-(void) process:(SimpleOperation*) op {
    // Attempt to make the post
    if ( op != nil ){
        NSURLRequest* request = [SimpleTwitterRequest postRequest:op oauth:_oAuth];
        if ( request != nil ) {
            // Only logging to NSLog to prevent compiler warnings
            NSURLConnection *conn = [[NSURLConnection alloc]
									 initWithRequest:request delegate:self];
            NSLog(@"%s: posting with connection: %@", __PRETTY_FUNCTION__, conn);
            return;
        }
    }
    if ([MediaShareBBUtilityMethods isObject:super.delegate
						  respondsToSelector:@selector(loginFailedWithError:)]) {
		[super.delegate loginFailedWithError:nil];
    }
}

-(void) performPost {
	if ([self canProceedRequestToShareWithNativeDialog]) {
		[self performNativeTwitterPost:_sharedMediaData];
	} else {
		if ([MediaShareBBUtilityMethods isObject:super.delegate
							  respondsToSelector:@selector(willSharingMedia:through:)]) {
			[super.delegate willSharingMedia:_sharedMediaData through:self];
		}
		[self performCustomTwitterPost:_sharedMediaData];
	}
}

-(void) performCustomTwitterPost:(MediaShareData*) data {
	[self performCustomTwitterPost:data.fileName
						withImages:[NSArray arrayWithObject:[MediaShareBBUtilityMethods
															 imageFromData:data.data]]
						   withURL:nil];
}

-(void) performNativeTwitterPost:(MediaShareData*) data {
	[self performNativeTwitterPost:@""
						withImages:[NSArray arrayWithObject:[MediaShareBBUtilityMethods
															 imageFromData:data.data]]
						   withURL:nil];
}

-(void) performCustomTwitterPost:(NSString*) text
					  withImages:(NSArray*) images
						 withURL:(NSString*) url {
    if ( [MediaShareBBUtilityMethods isEmpty:_oAuth.oauth_consumer_key]) {
		NSLog(@"%s: Problem with oAuth consumer key. Can't post", __PRETTY_FUNCTION__);
    }
    SimpleOperation *op = [[SimpleOperation alloc] init];
    op.text = text;
    op.url = url;
    op.images = (images == nil) ? nil : [NSMutableArray arrayWithArray:images];
    [_queue enqueueObj:op];
    if (_oAuth.oauth_token_authorized ) {
        [self processQueue];
    } else {
        [self prepareLoginViewController];
    }
}

-(void) performNativeTwitterPost:(NSString*) text
					  withImages:(NSArray*) images
						 withURL:(NSString*) url {
	BOOL canProceed = [self canProceedRequestToShareWithNativeDialog];
	if (canProceed) {
		id tweet = [self createComposeViewController];
		if (tweet != nil) {
            [tweet setInitialText:text];
			[self setImages:images toTwitterViewController:tweet];
            if (url != nil ) {
				[tweet addURL:[NSURL URLWithString:url]];
			}
			void (^completionBlock)(BOOL resultDone) = ^(BOOL resultDone) {
				[self dismissViewController];
				if (resultDone && [MediaShareBBUtilityMethods isObject:super.delegate
													respondsToSelector:@selector(didFinishSharingMedia:through:)]) {
					[super.delegate didFinishSharingMedia:_sharedMediaData
												  through:self];
				} else if (!resultDone) {
					[super.delegate communityViewWillClose];
				}
            };
			[self setCompletionHandlersToTwitterViewController:tweet
													completion:completionBlock];
			[self presentViewController:tweet];
		}
	}
}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-(BOOL) canProceedRequestToShareWithNativeDialog {
    BOOL result = NO;
	if (IOS5) {
		result = [SLComposeViewController
				  isAvailableForServiceType:SLServiceTypeTwitter];
	} else if (IOS6) {
		result = [TWTweetComposeViewController canSendTweet];
    }
	return result;
}
#pragma clang diagnostic pop

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-(id) createComposeViewController {
	id vc = nil;
	if (IOS5) {
		vc = [[TWTweetComposeViewController alloc] init];
	} else if (IOS6) {
		vc = [SLComposeViewController
			  composeViewControllerForServiceType:SLServiceTypeTwitter];
	}
	return vc;
}
#pragma clang diagnostic pop

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-(void) setImages:(NSArray*) images toTwitterViewController:(id) tweet {
	if (images != nil ) {
		for (UIImage* image in images ) {
			if (IOS5) {
				[(TWTweetComposeViewController*) tweet addImage:image];
			} else if (IOS6) {
				[(SLComposeViewController*) tweet addImage:image];
			}
		}
	}
}
#pragma clang diagnostic pop

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-(void) setCompletionHandlersToTwitterViewController:(id) tweet
										  completion:(void (^)(BOOL)) completionBlock {
    if (IOS5) {
        [(TWTweetComposeViewController*)tweet
		 setCompletionHandler:^(TWTweetComposeViewControllerResult result) {
			 BOOL resultDone = NO;
			 switch (result) {
				 case TWTweetComposeViewControllerResultDone:
					resultDone = YES;
                    break;
				 case TWTweetComposeViewControllerResultCancelled:
                    break;
			 }
            completionBlock(resultDone);
		}];
    }
    if (IOS6) {
        [(SLComposeViewController*)tweet
		 setCompletionHandler:^(SLComposeViewControllerResult result) {
			 BOOL resultDone = NO;
            switch (result) {
                case SLComposeViewControllerResultDone:
					resultDone = YES;
                    break;
                case SLComposeViewControllerResultCancelled:
                    break;
            }
			 completionBlock(resultDone);
        }];
    }
}

#pragma clang diagnostic pop

-(BOOL) isAuthenticated {
	return _oAuth.oauth_token_authorized;
}

@end
